/*
 * @Author: Wangjun
 * @Date: 2021-08-04 17:56:00
 * @LastEditTime: 2022-07-14 10:15:30
 * @LastEditors: Wangjun
 * @Description:定长队列
 * @FilePath: \golib\fixedqueue\queue.go
 * hnxr
 */

package fixedqueue

type FixedQueueFloat struct {
	array []float64
	begin uint //当前队列位置
	end   uint //累加器
	max   uint
}

/**
 * @description: 新建一个定长队列，只有写，没有读的数据
 * @param {int} size
 * @return {*}
 */
func NewFixedQueueFloat(size int) *FixedQueueFloat {
	m := new(FixedQueueFloat)
	m.SetSize(size)
	return m
}

/**
 * @description: 初始化队列的最大值
 * @param {int} maxLines
 * @return {*}
 */
func (m *FixedQueueFloat) SetSize(maxLines int) {
	if maxLines < 2 {
		maxLines = 2
	}
	if maxLines > 20000 {
		maxLines = 20000
	}
	m.array = make([]float64, maxLines)
	m.max = uint(maxLines)
	m.end = 0
	m.begin = 0
}

/**
 * @description:求和
 * @param {*}
 * @return {*}
 */
func (m *FixedQueueFloat) Sum() (sum float64, count int) {
	count = int(m.end)
	if count >= int(m.max) {
		count = int(m.max)
	}
	for i := 0; i < count; i++ {
		sum += m.array[i]
	}
	return sum, count
}

/**
 * @description: 求平均值
 * @param {*}
 * @return {*}
 */
func (m *FixedQueueFloat) Avg() (avg float64, count int) {
	count = int(m.end)
	if count >= int(m.max) {
		count = int(m.max)
	}
	for i := 0; i < count; i++ {
		avg += m.array[i]
	}
	if count > 0 {
		avg = avg / float64(count)
	}
	return
}

/**
 * @description: 压入数据
 * @param {*EventLog} e
 * @return {*}
 */
func (m *FixedQueueFloat) Push(e float64) {
	m.array[m.begin] = e
	m.end++
	m.begin = m.end % m.max
}

/**
 * @description:  倒序查找
 * @param {*} begin
 * @param {int} limit
 * @return {*}
 */
func (m *FixedQueueFloat) Page(begin, limit int) []float64 {
	end := begin + limit
	count := m.Size()

	if count == 0 {
		return nil
	}

	if begin > count {
		return nil
	}

	if limit > count {
		limit = count
	}

	if end > count {
		end = count
		limit = end - begin
	}
	rows := make([]float64, limit)

	idx := m.end
	pos := m.begin
	if idx < m.max { //队列没有循环一次
		if uint(begin) > idx {
			return nil
		}
		if uint(end) > idx {
			end = int(idx)
		}
		//m.array[begin:end]
		ii := 0
		for i := end - 1; i >= begin; i-- {
			rows[ii] = m.array[i]
			ii++
		}
		return rows
	}
	//倒序
	for i := 0; i < limit; i++ {
		index := int(pos+m.max) + i
		index %= int(m.max)
		rows[limit-i-1] = m.array[index]
	}

	return rows
}

/**
 * @description: 获取队列数据大小
 * @param {*}
 * @return {*}
 */
func (m *FixedQueueFloat) Size() int {
	if m.end >= m.max {
		return int(m.max)
	}
	return int(m.end)
}

/**
 * @description: 复位
 * @param {*}
 * @return {*}
 */
func (m *FixedQueueFloat) Reset() {
	m.end = 0
	m.begin = 0
}
